#tag Class
Protected Class NSApplicationNotificationObserver
Inherits CocoaDelegate
	#tag Event
		Function DelegateClassName() As String
		  
		  return "MLNSApplicationNotificationObserver"
		  
		End Function
	#tag EndEvent

	#tag Event
		Function DelegateMethods() As Tuple()
		  
		  dim methodList() as Tuple
		  methodList.Append kNotificationSelector : FPtr(AddressOf DispatchNotification) : "v@:@"
		  
		  return methodList
		  
		End Function
	#tag EndEvent


	#tag Method, Flags = &h1000
		Sub Constructor(handler as NSApplicationNotificationInterface = nil)
		  
		  // construct a delegate and accept an optional delegate handler which is a NSApplicationNotificationInterface instance
		  // this permits to use this class in two modes:
		  //
		  // 1. Without subclassing, just instantiating it passing a NSApplicationNotificationInterface member that will handle
		  //     the events (eg. a window or another class). The handler can also be changed at any time setting the DelegateHandler
		  //     property.
		  //
		  // 2. Subclassing this class and handling the events. This can be also done dragging an instance of this class in a window.
		  //
		  
		  // store the handler
		  DelegateHandler = handler
		  
		  // call super to construct the object
		  super.Constructor
		  
		  // raise the Open event (for use by subclasses or instances dragged to a window)
		  raiseEvent Open()
		  
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub Destructor()
		  
		  // if we are registered as observer, we must unregister before getting deallocated or a runtime error will happen
		  if registered then
		    self.Unregister
		  end if
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h21
		Private Shared Sub DispatchNotification(id as Ptr, sel as Ptr, notification as Ptr)
		  
		  // dispatch the message to the right instance handler
		  
		  #pragma StackOverflowChecking false
		  
		  #pragma unused sel
		  
		  if CocoaDelegateMap.HasKey(id) then // lookup the delegate instance
		    dim w as WeakRef = CocoaDelegateMap.Lookup(id, new WeakRef(nil))
		    dim obj as NSApplicationNotificationObserver = NSApplicationNotificationObserver(w.Value) // get the delegate instance
		    
		    // be sure to have a valid object
		    if obj = nil then
		      return
		    end if
		    
		    // build objects to pass to the instance method
		    dim notificationObj as NSNotification
		    if notification <> nil then
		      notificationObj = new NSNotification(notification)
		      
		      // identify the notification and call the right handler
		      select case notificationObj.Name
		        
		      case "NSApplicationDidBecomeActiveNotification"
		        obj.NSApplication_DidBecomeActiveHandler notificationObj
		        
		      case "NSApplicationDidChangeScreenParametersNotification"
		        obj.NSApplication_DidChangeScreenParametersHandler notificationObj
		        
		      case "NSApplicationDidFinishLaunchingNotification"
		        obj.NSApplication_DidFinishLaunchingHandler notificationObj
		        
		      case "NSApplicationDidHideNotification"
		        obj.NSApplication_DidHideHandler notificationObj
		        
		      case "NSApplicationDidUnhideNotification"
		        obj.NSApplication_DidUnhideHandler notificationObj
		        
		        'case "NSApplicationDidUpdateNotification"
		        'obj.NSApplication_DidUpdateHandler notificationObj
		        
		      case "NSApplicationWillBecomeActiveNotification"
		        obj.NSApplication_WillBecomeActiveHandler notificationObj
		        
		      case "NSApplicationWillFinishLaunchingNotification"
		        obj.NSApplication_WillFinishLaunchingHandler notificationObj
		        
		      case "NSApplicationWillHideNotification"
		        obj.NSApplication_WillHideHandler notificationObj
		        
		      case "NSApplicationWillResignActiveNotification"
		        obj.NSApplication_WillResignActiveHandler notificationObj
		        
		      case "NSApplicationWillTerminateNotification"
		        obj.NSApplication_WillTerminateHandler notificationObj
		        
		      case "NSApplicationWillUnhideNotification"
		        obj.NSApplication_WillUnhideHandler notificationObj
		        
		        'case "NSApplicationWillUpdateNotification"
		        'obj.NSApplication_WillUpdateHandler notificationObj
		        
		      end select
		      
		    end if
		    
		  end if
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h21
		Private Sub NSApplication_DidBecomeActiveHandler(notification as NSNotification)
		  
		  // handle the message and call the handler or fire the event
		  
		  if DelegateHandler <> nil then
		    DelegateHandler.NSApplication_DidBecomeActive(notification)
		  else
		    raiseEvent NSApplication_DidBecomeActive(notification)
		  end if
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h21
		Private Sub NSApplication_DidChangeScreenParametersHandler(notification as NSNotification)
		  
		  // handle the message and call the handler or fire the event
		  
		  if DelegateHandler <> nil then
		    DelegateHandler.NSApplication_DidChangeScreenParameters(notification)
		  else
		    raiseEvent NSApplication_DidChangeScreenParameters(notification)
		  end if
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h21
		Private Sub NSApplication_DidFinishLaunchingHandler(notification as NSNotification)
		  
		  // handle the message and call the handler or fire the event
		  
		  if DelegateHandler <> nil then
		    DelegateHandler.NSApplication_DidFinishLaunching(notification)
		  else
		    raiseEvent NSApplication_DidFinishLaunching(notification)
		  end if
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h21
		Private Sub NSApplication_DidHideHandler(notification as NSNotification)
		  
		  // handle the message and call the handler or fire the event
		  
		  if DelegateHandler <> nil then
		    DelegateHandler.NSApplication_DidHide(notification)
		  else
		    raiseEvent NSApplication_DidHide(notification)
		  end if
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h21
		Private Sub NSApplication_DidUnhideHandler(notification as NSNotification)
		  
		  // handle the message and call the handler or fire the event
		  
		  if DelegateHandler <> nil then
		    DelegateHandler.NSApplication_DidUnhide(notification)
		  else
		    raiseEvent NSApplication_DidUnhide(notification)
		  end if
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h21
		Private Sub NSApplication_WillBecomeActiveHandler(notification as NSNotification)
		  
		  // handle the message and call the handler or fire the event
		  
		  if DelegateHandler <> nil then
		    DelegateHandler.NSApplication_WillBecomeActive(notification)
		  else
		    raiseEvent NSApplication_WillBecomeActive(notification)
		  end if
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h21
		Private Sub NSApplication_WillFinishLaunchingHandler(notification as NSNotification)
		  
		  // handle the message and call the handler or fire the event
		  
		  if DelegateHandler <> nil then
		    DelegateHandler.NSApplication_WillFinishLaunching(notification)
		  else
		    raiseEvent NSApplication_WillFinishLaunching(notification)
		  end if
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h21
		Private Sub NSApplication_WillHideHandler(notification as NSNotification)
		  
		  // handle the message and call the handler or fire the event
		  
		  if DelegateHandler <> nil then
		    DelegateHandler.NSApplication_WillHide(notification)
		  else
		    raiseEvent NSApplication_WillHide(notification)
		  end if
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h21
		Private Sub NSApplication_WillResignActiveHandler(notification as NSNotification)
		  
		  // handle the message and call the handler or fire the event
		  
		  if DelegateHandler <> nil then
		    DelegateHandler.NSApplication_WillResignActive(notification)
		  else
		    raiseEvent NSApplication_WillResignActive(notification)
		  end if
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h21
		Private Sub NSApplication_WillTerminateHandler(notification as NSNotification)
		  
		  // handle the message and call the handler or fire the event
		  
		  if DelegateHandler <> nil then
		    DelegateHandler.NSApplication_WillTerminate(notification)
		  else
		    raiseEvent NSApplication_WillTerminate(notification)
		  end if
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h21
		Private Sub NSApplication_WillUnhideHandler(notification as NSNotification)
		  
		  // handle the message and call the handler or fire the event
		  
		  if DelegateHandler <> nil then
		    DelegateHandler.NSApplication_WillUnhide(notification)
		  else
		    raiseEvent NSApplication_WillUnhide(notification)
		  end if
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub Register()
		  
		  // These notifications are accessible through the shared default notification center
		  
		  // only proceed if we are not already registered
		  if not registered then
		    // get the notification center
		    dim center as NSNotificationCenter = NSNotificationCenter.DefaultCenter
		    
		    // register self as observer
		    
		    // registering for all notifications will include
		    // NSApplicationDidUpdateNotification and NSApplicationWillUpdateNotification notifications
		    // which cause a stack overflow for repeatly getting notified about windows upadates
		    
		    'center.AddObserver self, kNotificationSelector, "", nil
		    
		    // So we need to individually subscribe all notifications but the two above
		    center.AddObserver self, kNotificationSelector, "NSApplicationDidBecomeActiveNotification", nil
		    center.AddObserver self, kNotificationSelector, "NSApplicationDidChangeScreenParametersNotification", nil
		    center.AddObserver self, kNotificationSelector, "NSApplicationDidFinishLaunchingNotification", nil
		    center.AddObserver self, kNotificationSelector, "NSApplicationDidHideNotification", nil
		    center.AddObserver self, kNotificationSelector, "NSApplicationDidUnhideNotification", nil
		    center.AddObserver self, kNotificationSelector, "NSApplicationWillBecomeActiveNotification", nil
		    center.AddObserver self, kNotificationSelector, "NSApplicationWillFinishLaunchingNotification", nil
		    center.AddObserver self, kNotificationSelector, "NSApplicationWillHideNotification", nil
		    center.AddObserver self, kNotificationSelector, "NSApplicationWillResignActiveNotification", nil
		    center.AddObserver self, kNotificationSelector, "NSApplicationWillTerminateNotification", nil
		    center.AddObserver self, kNotificationSelector, "NSApplicationWillUnhideNotification", nil
		    
		    // mark we registered as observer
		    registered = true
		  end if
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub Unregister()
		  
		  // These notifications are accessible through the shared default notification center
		  
		  // only proceed if we are currently registered
		  if registered then
		    // get the notification center
		    dim center as NSNotificationCenter = NSNotificationCenter.DefaultCenter
		    
		    // unregister self as observer
		    center.RemoveObserver self
		    
		    // mark we are no longer registered as observer
		    registered = false
		  end if
		End Sub
	#tag EndMethod


	#tag Hook, Flags = &h0
		Event NSApplication_DidBecomeActive(notification as NSNotification)
	#tag EndHook

	#tag Hook, Flags = &h0
		Event NSApplication_DidChangeScreenParameters(notification as NSNotification)
	#tag EndHook

	#tag Hook, Flags = &h0
		Event NSApplication_DidFinishLaunching(notification as NSNotification)
	#tag EndHook

	#tag Hook, Flags = &h0
		Event NSApplication_DidHide(notification as NSNotification)
	#tag EndHook

	#tag Hook, Flags = &h0
		Event NSApplication_DidUnhide(notification as NSNotification)
	#tag EndHook

	#tag Hook, Flags = &h0
		Event NSApplication_WillBecomeActive(notification as NSNotification)
	#tag EndHook

	#tag Hook, Flags = &h0
		Event NSApplication_WillFinishLaunching(notification as NSNotification)
	#tag EndHook

	#tag Hook, Flags = &h0
		Event NSApplication_WillHide(notification as NSNotification)
	#tag EndHook

	#tag Hook, Flags = &h0
		Event NSApplication_WillResignActive(notification as NSNotification)
	#tag EndHook

	#tag Hook, Flags = &h0
		Event NSApplication_WillTerminate(notification as NSNotification)
	#tag EndHook

	#tag Hook, Flags = &h0
		Event NSApplication_WillUnhide(notification as NSNotification)
	#tag EndHook

	#tag Hook, Flags = &h0
		Event Open()
	#tag EndHook


	#tag Property, Flags = &h0
		DelegateHandler As NSApplicationNotificationInterface
	#tag EndProperty

	#tag Property, Flags = &h21
		Private registered As Boolean
	#tag EndProperty


	#tag Constant, Name = kNotificationSelector, Type = String, Dynamic = False, Default = \"dispatchApplicationNotification:", Scope = Private
	#tag EndConstant


	#tag ViewBehavior
		#tag ViewProperty
			Name="ClassName"
			Group="Behavior"
			Type="String"
			EditorType="MultiLineEditor"
			InheritedFrom="CocoaDelegate"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Description"
			Group="Behavior"
			Type="String"
			EditorType="MultiLineEditor"
			InheritedFrom="NSObject"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Index"
			Visible=true
			Group="ID"
			InitialValue="-2147483648"
			Type="Integer"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Left"
			Visible=true
			Group="Position"
			InitialValue="0"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Name"
			Visible=true
			Group="ID"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Super"
			Visible=true
			Group="ID"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Top"
			Visible=true
			Group="Position"
			InitialValue="0"
			InheritedFrom="Object"
		#tag EndViewProperty
	#tag EndViewBehavior
End Class
#tag EndClass
